/*
Source : https://leetcode.com/problems/validate-binary-search-tree/
Author : nflush@outlook.com
Date   : 2016-07-05
*/

/*
98. Validate Binary Search Tree

    Total Accepted: 99751
    Total Submissions: 470315
    Difficulty: Medium

Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

    The left subtree of a node contains only nodes with keys less than the node's key.
    The right subtree of a node contains only nodes with keys greater than the node's key.
    Both the left and right subtrees must also be binary search trees.

Example 1:

    2
   / \
  1   3

Binary tree [2,1,3], return true.

Example 2:

    1
   / \
  2   3

Binary tree [1,2,3], return false. 
*/
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    bool isValidBSTIn(TreeNode* root, int *max, int *min){
        if (root->left){
            if (root->left->val >= root->val || (min && root->left->val <= *min))
                return false;

            if (!isValidBSTIn(root->left, &root->val, min))
                return false;
        }
        if (root->right){
            if (root->right->val <= root->val || (max && root->right->val >= *max))
                return false;

            if (!isValidBSTIn(root->right, max, &root->val))
                return false;
        }
        return true;
    }
public:
    bool isValidBST(TreeNode* root) {
        if (!root) return true;
        if (root->left){
            if (root->left->val >= root->val)
                return false;

            if (!isValidBSTIn(root->left, &root->val, NULL))
                return false;
        }
        if (root->right){
            if (root->right->val <= root->val)
                return false;

            if (!isValidBSTIn(root->right, NULL, &root->val))
                return false;
        }
        return true;
    }
};

//travel the tree by inner-order
class Solution {
private:
    bool isValidBSTIn(TreeNode* root, int *&cur){
        if (!root) return true;
        if (!isValidBSTIn(root->left, cur)){
            return false;
        }
        if (cur && *cur >= root->val){
            return false;
        }
        cur = &root->val;
        
        return isValidBSTIn(root->right, cur);
    }
public:
    bool isValidBST(TreeNode* root) {
        if (!root) return true;
        int *cur = NULL;

        return isValidBSTIn(root, cur);
    }
};


